"""
Demo Conversations

This module provides demonstration scripts showing cross-temporal conversations
between historical figures, showcasing the full capabilities of the AI Historical
Simulation Platform.
"""

import asyncio
import json
import logging
from datetime import datetime
from typing import List, Dict, Any, Optional
from pathlib import Path

logger = logging.getLogger(__name__)


class DemoConversations:
    """
    Demonstration scripts for cross-temporal historical figure conversations.
    
    This class provides pre-configured conversation scenarios that demonstrate
    the platform's capabilities for educational and research purposes.
    """
    
    def __init__(self, platform):
        """
        Initialize the demo conversations.
        
        Args:
            platform: The AI Historical Simulation Platform instance
        """
        self.platform = platform
        self.demo_results_dir = Path('demo_results')
        self.demo_results_dir.mkdir(exist_ok=True)
        
        # Define available demonstration scenarios
        self.available_demos = {
            'napoleon_caesar': {
                'name': 'Napoleon and Caesar: Military Strategy Discussion',
                'description': 'Two great military leaders discuss strategy, tactics, and leadership',
                'figures': ['Napoleon Bonaparte', 'Julius Caesar'],
                'topics': [
                    'What makes a great military leader?',
                    'How do you adapt tactics to different terrains?',
                    'What role does logistics play in military campaigns?'
                ]
            },
            'leonardo_modern': {
                'name': 'Leonardo da Vinci meets Modern Innovation',
                'description': 'Renaissance genius discusses creativity and innovation with contemporary perspective',
                'figures': ['Leonardo da Vinci'],
                'topics': [
                    'How do you approach creative problem solving?',
                    'What is the relationship between art and science?',
                    'How would you design solutions for modern challenges?'
                ]
            },
            'philosophy_debate': {
                'name': 'Cross-Era Philosophy Debate',
                'description': 'Philosophers from different eras debate fundamental questions',
                'figures': ['Julius Caesar', 'Leonardo da Vinci'],  # Using available figures for philosophical discussion
                'topics': [
                    'What is the nature of power and governance?',
                    'How should society balance individual creativity with collective needs?',
                    'What drives human progress and innovation?'
                ]
            },
            'leadership_summit': {
                'name': 'Historical Leadership Summit',
                'description': 'Great leaders discuss leadership principles across eras',
                'figures': ['Napoleon Bonaparte', 'Julius Caesar'],
                'topics': [
                    'What are the essential qualities of effective leadership?',
                    'How do you inspire loyalty and dedication?',
                    'How has leadership evolved across different eras?'
                ]
            }
        }
    
    def list_available_demos(self) -> List[str]:
        """Get list of available demonstration scenarios."""
        return list(self.available_demos.keys())
    
    async def run_all_demos(self) -> Dict[str, Any]:
        """
        Run all available demonstration scenarios.
        
        Returns:
            Results from all demonstrations
        """
        print("🎭 Running all demonstration scenarios...")
        print("=" * 60)
        
        all_results = {
            'timestamp': datetime.now().isoformat(),
            'total_demos': len(self.available_demos),
            'demo_results': {}
        }
        
        for demo_id in self.available_demos.keys():
            print(f"\n🎪 Starting demo: {demo_id}")
            try:
                result = await self.run_specific_conversation(demo_id)
                all_results['demo_results'][demo_id] = result
                print(f"✓ Completed demo: {demo_id}")
            except Exception as e:
                print(f"✗ Failed demo: {demo_id} - {e}")
                all_results['demo_results'][demo_id] = {'error': str(e)}
        
        # Save comprehensive results
        results_file = self.demo_results_dir / f"all_demos_{self.platform.get_timestamp()}.json"
        with open(results_file, 'w') as f:
            json.dump(all_results, f, indent=2)
        
        print(f"\n📊 All demonstrations complete! Results saved to: {results_file}")
        return all_results
    
    async def run_specific_conversation(self, demo_id: str) -> Dict[str, Any]:
        """
        Run a specific demonstration conversation.
        
        Args:
            demo_id: ID of the demonstration to run
            
        Returns:
            Conversation results and analysis
        """
        if demo_id not in self.available_demos:
            available = ', '.join(self.available_demos.keys())
            raise ValueError(f"Demo '{demo_id}' not available. Available: {available}")
        
        demo_config = self.available_demos[demo_id]
        
        print(f"\n🎭 {demo_config['name']}")
        print(f"📖 {demo_config['description']}")
        print("=" * 60)
        
        # Load required figures
        figures = []
        for figure_name in demo_config['figures']:
            try:
                figure = await self.platform.load_historical_figure(figure_name)
                figures.append(figure)
                print(f"✓ Loaded: {figure.name}")
            except Exception as e:
                print(f"✗ Failed to load {figure_name}: {e}")
                return {'error': f'Failed to load figure: {figure_name}'}
        
        conversation_results = {
            'demo_id': demo_id,
            'demo_name': demo_config['name'],
            'timestamp': datetime.now().isoformat(),
            'figures': [f.name for f in figures],
            'conversations': []
        }
        
        # Run conversations on each topic
        for i, topic in enumerate(demo_config['topics'], 1):
            print(f"\n💬 Topic {i}: {topic}")
            print("-" * 40)
            
            try:
                if len(figures) > 1:
                    # Multi-figure cross-temporal conversation
                    conversation = await self.platform.create_cross_temporal_conversation(
                        [f.name for f in figures],
                        topic
                    )
                else:
                    # Single figure conversation
                    conversation = await self._single_figure_conversation(figures[0], topic)
                
                conversation_results['conversations'].append({
                    'topic': topic,
                    'exchanges': conversation
                })
                
                # Display conversation
                self._display_conversation(conversation, topic)
                
            except Exception as e:
                print(f"✗ Error in topic {i}: {e}")
                conversation_results['conversations'].append({
                    'topic': topic,
                    'error': str(e)
                })
        
        # Analyze and save results
        analysis = self._analyze_conversation_results(conversation_results)
        conversation_results['analysis'] = analysis
        
        # Save individual demo results
        results_file = self.demo_results_dir / f"{demo_id}_{self.platform.get_timestamp()}.json"
        with open(results_file, 'w') as f:
            json.dump(conversation_results, f, indent=2)
        
        print(f"\n📊 Demo '{demo_id}' complete! Results saved to: {results_file}")
        self._display_analysis(analysis)
        
        return conversation_results
    
    async def create_custom_demo(self, figures: List[str], topics: List[str], 
                                name: str = "Custom Demo") -> Dict[str, Any]:
        """
        Create and run a custom demonstration.
        
        Args:
            figures: List of historical figure names
            topics: List of conversation topics
            name: Name for the custom demo
            
        Returns:
            Custom demonstration results
        """
        print(f"\n🎨 {name}")
        print("=" * 60)
        
        # Validate figures
        available_figures = self.platform.figure_manager.list_available_figures()
        for figure_name in figures:
            if figure_name not in available_figures:
                raise ValueError(f"Figure '{figure_name}' not available. Available: {available_figures}")
        
        custom_demo = {
            'name': name,
            'description': f'Custom demonstration with {", ".join(figures)}',
            'figures': figures,
            'topics': topics
        }
        
        # Add to available demos temporarily
        demo_id = f'custom_{int(datetime.now().timestamp())}'
        self.available_demos[demo_id] = custom_demo
        
        try:
            result = await self.run_specific_conversation(demo_id)
            return result
        finally:
            # Remove temporary demo
            self.available_demos.pop(demo_id, None)
    
    async def educational_demo_sequence(self) -> Dict[str, Any]:
        """
        Run a sequence of demonstrations designed for educational purposes.
        
        Returns:
            Educational demo sequence results
        """
        print("\n🎓 Educational Demo Sequence")
        print("=" * 60)
        print("This sequence demonstrates the platform's educational capabilities")
        print("through progressively complex historical interactions.\n")
        
        sequence_results = {
            'timestamp': datetime.now().isoformat(),
            'sequence_type': 'educational',
            'stages': []
        }
        
        # Stage 1: Individual Figure Introduction
        print("📚 Stage 1: Individual Figure Introduction")
        stage1_result = await self._educational_stage_1()
        sequence_results['stages'].append(stage1_result)
        
        # Stage 2: Comparative Analysis
        print("\n🔍 Stage 2: Comparative Analysis")
        stage2_result = await self._educational_stage_2()
        sequence_results['stages'].append(stage2_result)
        
        # Stage 3: Cross-Temporal Discussion
        print("\n🌉 Stage 3: Cross-Temporal Discussion")
        stage3_result = await self._educational_stage_3()
        sequence_results['stages'].append(stage3_result)
        
        # Save educational sequence results
        results_file = self.demo_results_dir / f"educational_sequence_{self.platform.get_timestamp()}.json"
        with open(results_file, 'w') as f:
            json.dump(sequence_results, f, indent=2)
        
        print(f"\n🎓 Educational sequence complete! Results saved to: {results_file}")
        return sequence_results
    
    # Private methods
    
    async def _single_figure_conversation(self, figure, topic: str) -> List[Dict[str, Any]]:
        """Create a conversation with a single historical figure."""
        session_id = f"demo_{int(datetime.now().timestamp())}"
        
        # Generate multiple questions about the topic
        questions = [
            f"What are your thoughts on {topic.lower()}?",
            f"Can you elaborate on your perspective regarding {topic.lower()}?",
            f"How would you apply your experience to {topic.lower()}?"
        ]
        
        conversation = []
        
        for question in questions:
            response = await self.platform.generate_response(
                figure.personality_id,
                question,
                session_id
            )
            
            conversation.append({
                'figure': figure.name,
                'input': question,
                'response': response,
                'timestamp': datetime.now().isoformat()
            })
        
        return conversation
    
    def _display_conversation(self, conversation: List[Dict[str, Any]], topic: str) -> None:
        """Display a conversation in a readable format."""
        print(f"💭 Topic: {topic}")
        
        for exchange in conversation:
            if 'figure' in exchange:
                # Single figure conversation format
                print(f"\n👤 {exchange['figure']}:")
                print(f"   {exchange['response']}")
            else:
                # Multi-figure conversation format
                print(f"\n👤 {exchange['figure']}:")
                print(f"   💬 Responding to: \"{exchange['input'][:100]}{'...' if len(exchange['input']) > 100 else ''}\"")
                print(f"   💭 Response: {exchange['response']}")
    
    def _analyze_conversation_results(self, results: Dict[str, Any]) -> Dict[str, Any]:
        """Analyze conversation results and provide insights."""
        analysis = {
            'total_topics': len(results['conversations']),
            'total_exchanges': 0,
            'average_response_length': 0,
            'figures_participation': {},
            'topics_analysis': [],
            'conversation_quality': 'good'  # Simplified quality assessment
        }
        
        total_response_length = 0
        
        for conversation in results['conversations']:
            if 'error' in conversation:
                continue
            
            topic_analysis = {
                'topic': conversation['topic'],
                'exchanges_count': len(conversation['exchanges']),
                'participants': []
            }
            
            for exchange in conversation['exchanges']:
                analysis['total_exchanges'] += 1
                
                if 'response' in exchange:
                    response_length = len(exchange['response'])
                    total_response_length += response_length
                    
                    figure = exchange.get('figure', 'Unknown')
                    if figure not in analysis['figures_participation']:
                        analysis['figures_participation'][figure] = 0
                    analysis['figures_participation'][figure] += 1
                    
                    if figure not in topic_analysis['participants']:
                        topic_analysis['participants'].append(figure)
            
            analysis['topics_analysis'].append(topic_analysis)
        
        if analysis['total_exchanges'] > 0:
            analysis['average_response_length'] = total_response_length / analysis['total_exchanges']
        
        # Quality assessment based on participation and response lengths
        if analysis['average_response_length'] > 100 and analysis['total_exchanges'] > 5:
            analysis['conversation_quality'] = 'excellent'
        elif analysis['average_response_length'] > 50 and analysis['total_exchanges'] > 3:
            analysis['conversation_quality'] = 'good'
        else:
            analysis['conversation_quality'] = 'fair'
        
        return analysis
    
    def _display_analysis(self, analysis: Dict[str, Any]) -> None:
        """Display conversation analysis."""
        print(f"\n📊 Conversation Analysis")
        print("-" * 30)
        print(f"Total Topics: {analysis['total_topics']}")
        print(f"Total Exchanges: {analysis['total_exchanges']}")
        print(f"Average Response Length: {analysis['average_response_length']:.0f} characters")
        print(f"Conversation Quality: {analysis['conversation_quality']}")
        
        if analysis['figures_participation']:
            print(f"\nFigure Participation:")
            for figure, count in analysis['figures_participation'].items():
                print(f"  {figure}: {count} responses")
    
    async def _educational_stage_1(self) -> Dict[str, Any]:
        """Educational stage 1: Individual figure introduction."""
        print("Introducing individual historical figures...")
        
        stage_result = {
            'stage': 1,
            'name': 'Individual Figure Introduction',
            'figures_introduced': []
        }
        
        figures_to_introduce = ['Napoleon Bonaparte', 'Julius Caesar', 'Leonardo da Vinci']
        
        for figure_name in figures_to_introduce:
            try:
                figure = await self.platform.load_historical_figure(figure_name)
                
                # Simple introduction conversation
                intro_response = await self.platform.generate_response(
                    figure.personality_id,
                    "Please introduce yourself and tell us about your most significant achievements.",
                    f"educational_stage1_{figure_name}"
                )
                
                stage_result['figures_introduced'].append({
                    'name': figure.name,
                    'introduction': intro_response
                })
                
                print(f"✓ Introduced: {figure.name}")
                
            except Exception as e:
                print(f"✗ Failed to introduce {figure_name}: {e}")
        
        return stage_result
    
    async def _educational_stage_2(self) -> Dict[str, Any]:
        """Educational stage 2: Comparative analysis."""
        print("Conducting comparative analysis...")
        
        stage_result = {
            'stage': 2,
            'name': 'Comparative Analysis',
            'comparisons': []
        }
        
        # Compare military leaders
        comparison_topic = "leadership and decision-making in challenging situations"
        
        try:
            conversation = await self.platform.create_cross_temporal_conversation(
                ['Napoleon Bonaparte', 'Julius Caesar'],
                comparison_topic
            )
            
            stage_result['comparisons'].append({
                'figures': ['Napoleon Bonaparte', 'Julius Caesar'],
                'topic': comparison_topic,
                'conversation': conversation
            })
            
            print(f"✓ Compared military leadership approaches")
            
        except Exception as e:
            print(f"✗ Failed comparison: {e}")
        
        return stage_result
    
    async def _educational_stage_3(self) -> Dict[str, Any]:
        """Educational stage 3: Cross-temporal discussion."""
        print("Facilitating cross-temporal discussion...")
        
        stage_result = {
            'stage': 3,
            'name': 'Cross-Temporal Discussion',
            'discussions': []
        }
        
        # Complex multi-era discussion
        discussion_topic = "the relationship between innovation and societal progress"
        
        try:
            # Since we have limited figures, we'll create a rich discussion with available ones
            available_figures = self.platform.figure_manager.list_available_figures()
            selected_figures = available_figures[:2] if len(available_figures) >= 2 else available_figures
            
            if selected_figures:
                conversation = await self.platform.create_cross_temporal_conversation(
                    selected_figures,
                    discussion_topic
                )
                
                stage_result['discussions'].append({
                    'figures': selected_figures,
                    'topic': discussion_topic,
                    'conversation': conversation
                })
                
                print(f"✓ Cross-temporal discussion completed")
            
        except Exception as e:
            print(f"✗ Failed cross-temporal discussion: {e}")
        
        return stage_result


# Standalone execution for testing
async def main():
    """Main function for standalone testing."""
    import sys
    import os
    
    # Add src to path
    sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
    
    from app.historical_platform import AIHistoricalSimulationPlatform
    
    # Initialize platform
    platform = AIHistoricalSimulationPlatform()
    await platform.initialize()
    
    # Create demo instance
    demo = DemoConversations(platform)
    
    # Run a simple demo
    print("🎭 Running Demo Conversations Test")
    
    try:
        await demo.run_specific_conversation('napoleon_caesar')
    except Exception as e:
        print(f"Demo failed: {e}")
    finally:
        await platform.cleanup()


if __name__ == "__main__":
    asyncio.run(main())